package com.retrofit.server.processor.old;

import com.retrofit.server.processor.Print;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import java.util.ArrayList;
import java.util.List;
import javax.lang.model.type.TypeMirror;

/**
 * 接口类中方法定义
 */
public class AnnotationClassMethod {

  /**
   * 方法名称
   */
  private String methodName;
  /**
   * 方法注解 处理 @BindResponseHandler
   */
  private MethodAnnotation methodAnnotation;
  /**
   * 方法参数
   */
  private List<MethodParam> params;
  /**
   * 方法参数名称，多个使用“,”分隔
   */
  private String methodParamNames;
  
  /**
   * 方法回调参数
   */
  private MethodHandlerParam methodHandlerParam;
  /**
   * 方法代码块
   */
  private CodeBlock codeBlock;

  /**
   * 方法return
   * */
  private MethodReturn methodReturn;

  /**
   * 方法的注释块
   */
  private CodeBlock codeBlockJavadoc;


  public String getMethodName() {
    return methodName;
  }

  public void setMethodName(String methodName) {
    this.methodName = methodName;
  }


  public void addParams(MethodParam param) {
    if(this.params==null){
      this.params=new ArrayList<>();
    }
    this.params.add(param);
  }

  public List<MethodParam> getParams() {
    return params;
  }

  public String getMethodParamNames() {
    return methodParamNames;
  }

  /**
   * 方法参数名称， 多个使用 ',' 分隔
   * @param methodParamNames
   */
  public void setMethodParamNames(String methodParamNames) {
    this.methodParamNames = methodParamNames;
  }

  public MethodHandlerParam getMethodHandlerParam() {
    return methodHandlerParam;
  }

  public void setMethodHandlerParam(
      MethodHandlerParam methodHandlerParam) {
    this.methodHandlerParam = methodHandlerParam;
  }

  public CodeBlock getCodeBlock() {
    return codeBlock;
  }

  public void setCodeBlock(CodeBlock codeBlock) {
    this.codeBlock = codeBlock;
  }

  public MethodAnnotation getMethodAnnotation() {
    return methodAnnotation;
  }

  public void setMethodAnnotation(
      MethodAnnotation methodAnnotation) {
    this.methodAnnotation = methodAnnotation;
  }

  public MethodReturn getMethodReturn() {
    return methodReturn;
  }

  public void setMethodReturn(
      MethodReturn methodReturn) {
    this.methodReturn = methodReturn;
  }

  public CodeBlock getCodeBlockJavadoc() {
    if(codeBlockJavadoc==null){
      CodeBlock.Builder b=CodeBlock.builder();
      if(params!=null){
        for (MethodParam param : params) {
          b.add("@param $N \n",param.paramName);
        }
      }
      codeBlockJavadoc=b.build();
    }
    try{
      if(methodHandlerParam!=null){
        CodeBlock.Builder builder=codeBlockJavadoc.toBuilder();
        builder.add("@param $N  $T \n",methodHandlerParam.methodParamName,methodHandlerParam.parameterizedTypeName==null?methodHandlerParam.cbClassName:methodHandlerParam.parameterizedTypeName);
        builder.add("\n");
        codeBlockJavadoc=builder.build();
      }
    }catch (Exception e){
      Print.log(e.getMessage());
    }
    
    return codeBlockJavadoc;
  }

  public void setCodeBlockJavadoc(CodeBlock codeBlockJavadoc) {
    this.codeBlockJavadoc = codeBlockJavadoc;
  }

  /**
   * 接口服务中参数信息
   */
  public static class MethodParam{
  public String paramType;
  public String paramName;
  public String genericType;
  public TypeMirror typeMirror;

    /**
     *
     * @param paramType
     * @param paramName
     * @param genericType
     */
   public MethodParam(String paramType, String paramName, String genericType) {
     this.paramType = paramType;
     this.paramName = paramName;
     this.genericType = genericType;
     this.typeMirror=null;
   }

    public MethodParam(String paramName, TypeMirror typeMirror) {
      this.paramName = paramName;
      this.typeMirror = typeMirror;
    }
  }


  /**
   * 回调参数
   */
 public static class MethodHandlerParam{
   public String methodParamName;
   public ClassName cbClassName;
   public ParameterizedTypeName parameterizedTypeName;

   public MethodHandlerParam(String methodParamName,ClassName cbClassName,ParameterizedTypeName parameterizedTypeName){
     this.methodParamName=methodParamName;
     this.cbClassName=cbClassName;
     this.parameterizedTypeName=parameterizedTypeName;
   }

 }

  /**
   * 方法注解
   */
 public static class MethodAnnotation{

   /**
    * 回调类
    */
   public TypeMirror typeMirrorHandler;
   /**
    * 泛型类
    */
   public TypeMirror typeMirrorGenericity;
   
   /**
    * 是否要生成此方法接口实现
    * */
   public boolean isGenerate;
  
    /**
     * 是否为同步方法
     */
   public boolean isSync;

   public MethodAnnotation(TypeMirror typeMirrorHandler,
       TypeMirror typeMirrorGenericity) {
      this(typeMirrorHandler,typeMirrorGenericity,true);
   }

    public MethodAnnotation(TypeMirror typeMirrorHandler,
        TypeMirror typeMirrorGenericity, boolean isGenerate) {
      this.typeMirrorHandler = typeMirrorHandler;
      this.typeMirrorGenericity = typeMirrorGenericity;
      this.isGenerate = isGenerate;
    }
  
    public MethodAnnotation(TypeMirror typeMirrorHandler,
      TypeMirror typeMirrorGenericity, boolean isGenerate,boolean isSync) {
      this.typeMirrorHandler = typeMirrorHandler;
      this.typeMirrorGenericity = typeMirrorGenericity;
      this.isGenerate = isGenerate;
      this.isSync=isSync;
    }
  }

  /**
   * 方法return
   */
 public static class MethodReturn{

   /**
    * return 类型
    */
   public TypeName typeName;
   /**
    * 泛型名称
    */
   public String typeVariableName;

   public MethodReturn(Class clzz,String typeVariableName){
     this.typeName=TypeName.get(clzz);
     this.typeVariableName=typeVariableName;
   }

   public MethodReturn(TypeName typeName,String typeVariableName){
     this.typeName=typeName;
     this.typeVariableName=typeVariableName;
   }

 }


}
